﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TD.bom
{
    /// <summary>
    /// Gère une vague de monstres
    /// </summary>
    public class Wave
    {
        /// <summary>
        /// Carte à laquelle la vague appartient
        /// </summary>
        public Map Map { get; protected set; }

        /// <summary>
        /// Monstres de la vague
        /// </summary>
        public List<Monster> Monsters
        {
            get;
            protected set;
        }

        /// <summary>
        /// Index du dernier monstre envoyé
        /// </summary>
        public int IndexOfLastMonsterSent
        {
            get;
            protected set;
        }

        /// <summary>
        /// Compte à rebours gérant la sortie des monstres
        /// </summary>
        public CountDown OutputCountDown
        {
            get;
            protected set;
        }

        protected MapTemplate.WaveData m_waveData;


        /// <summary>
        /// Construit une vague de monstre à partir des données spécifiées
        /// </summary>
        /// <param name="p_map">Carte dans laquelle la vague arrive</param>
        /// <param name="p_waveData">Données de la vague telles que décrites dans le template de la carte</param>
        public Wave(Map p_map, MapTemplate.WaveData p_waveData)
        {
            // TODO : intégrité des paramètres

            // Dump des données de la vague
            m_waveData = p_waveData;

            // Construction des monstres de la vague
            Monsters = new List<Monster>();

            for (int i = 0; i < m_waveData.TotalMonsterCount; i++)
            {
                Monsters.Add(new Monster(p_map, m_waveData.MonsterTemplateName));
            }

            
        }

        /// <summary>
        /// Envoie la vague
        /// </summary>
        public void Lauch()
        {
            OutputCountDown = new CountDown(m_waveData.MonsterOutputPeriod);

            IndexOfLastMonsterSent = 0;

            Monsters[IndexOfLastMonsterSent].Go();
        }

        /// <summary>
        /// Iteration de la boucle "physique".
        /// </summary>
        public void DoPhysics()
        {
            // Y a-t-il encore des monstres à envoyer ?
            if (IndexOfLastMonsterSent + 1 < Monsters.Count)
            {
                // Oui, si le compte à rebours est expiré, il est temps d'envoyer un nouveau monstre
                if (OutputCountDown.HasExpired)
                {
                    Monsters[++IndexOfLastMonsterSent].Go();

                    // On relance le compte à rebours
                    OutputCountDown.Trigger(m_waveData.MonsterOutputPeriod);
                }
            }

            // Il faut également que chaque monstre sorti effectue son déplacement
            for (int i = IndexOfLastMonsterSent; i >= 0; i--)
            {
                // Si le monstre est en jeu, il gère son déplacement
                if (Monsters[i].InGame)
                {
                    Monsters[i].Move();
                }
            }
        }
    }
}
